#include "stdafx.h"
#include "util/util.h"
#include "dump.h"
#include "command.h"
#include <DbgHelp.h>

namespace shared
{
	namespace dump {
		BOOL CALLBACK AppMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input, PMINIDUMP_CALLBACK_OUTPUT output)
		{
			if (input == NULL || output == NULL)
				return FALSE;

			BOOL ret = FALSE;
			switch (input->CallbackType)
			{
			case IncludeModuleCallback:
			case IncludeThreadCallback:
			case ThreadCallback:
			case ThreadExCallback:
				ret = TRUE;
				break;
			case ModuleCallback:
			{
				if (!(output->ModuleWriteFlags & ModuleReferencedByMemory))
				{
					output->ModuleWriteFlags &= ~ModuleWriteModule;
				}
				ret = TRUE;
			}
			break;
			default:
				break;
			}

			return ret;
		}

		void AppWriteDump(EXCEPTION_POINTERS* exp, const std::wstring& path)
		{
			HANDLE h = ::CreateFile(path.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
				NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

			MINIDUMP_EXCEPTION_INFORMATION info;
			info.ThreadId = ::GetCurrentThreadId();
			info.ExceptionPointers = exp;
			info.ClientPointers = NULL;

			MINIDUMP_CALLBACK_INFORMATION mci;
			mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)AppMiniDumpCallback;
			mci.CallbackParam = 0;

			MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory);

			::MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), h, mdt, &info, NULL, &mci);
			::CloseHandle(h);
		}
	}
}



